use reqwest::Client;
use serde::{Deserialize, Serialize};

use crate::common::Response;

#[derive(Clone, Debug, Deserialize)]
pub struct KeyInfo {
    pub encrypt_key: String,
    pub version: u32,
    pub expire_in: u32,
    pub iv: String,
    pub create_time: u32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct UserEncryptKeyRes {
    pub key_info_list: Vec<KeyInfo>,
}

#[derive(Clone, Debug, Serialize)]
pub struct UserEncryptKeyReq {
    openid: String,
    signature: String,
    sig_method: String,
}

impl UserEncryptKeyReq {
    pub fn new<T>(openid: T, signature: T) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            openid: openid.as_ref().to_owned(),
            signature: signature.as_ref().to_owned(),
            sig_method: "hmac_sha256".to_owned(),
        }
    }
}

type Res = Response<UserEncryptKeyRes>;

pub async fn get_user_encrypt_key<T>(
    token: T,
    req: &UserEncryptKeyReq,
) -> Result<Res, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = format!(
        "https://api.weixin.qq.com/wxa/business/getuserencryptkey?access_token={}",
        token.as_ref()
    );
    let client = Client::new();
    client.post(url).json(req).send().await?.json::<Res>().await
}
